import java.nio.ByteBuffer;
import java.util.Arrays;

/**
 * An demo for http request reader.
 */
public class HTTPDemo {

	private static class HttpPacketReader {
		private class Indicator {

			private int onLightIndex;
			private int position;

			public Indicator() {
				reset();
			}

			public int getPosition() {
				return position;
			}

			public void reset() {
				onLightIndex = -1;
				position = 0;
			}

			public boolean test() {
				while (position + onLightIndex < buffer.position()) {
					if (LIGHTS[onLightIndex + 1].match(buffer.get(position
							+ onLightIndex + 1))) {
						onLightIndex++;
						if (onLightIndex == 3)
							return true;

					} else {
						position++;
						onLightIndex = -1;
					}
				}
				return false;
			}

		}

		private static class Light {
			private final byte b;

			Light(byte b) {
				this.b = b;
			}

			boolean match(byte compare) {
				return compare == b;
			}
		}

		private static final byte CR = '\r';
		private static final byte LF = '\n';
		private static final Light[] LIGHTS = new Light[4];

		static {
			LIGHTS[0] = new Light(CR);
			LIGHTS[1] = new Light(LF);
			LIGHTS[2] = new Light(CR);
			LIGHTS[3] = new Light(LF);
		}

		private ByteBuffer buffer;

		private Indicator indicator;

		HttpPacketReader() {
			buffer = ByteBuffer.allocate(40 * 1024);
			buffer.put(DEMO_DATA);
			indicator = new Indicator();
		}

		public void read() {
			while (indicator.test()) {
				int position = indicator.getPosition() + 3;
				byte[] header = new byte[position + 1];
				int oldPosition = buffer.position();
				int newPosition = oldPosition - position;
				buffer.position(0);
				buffer.get(header);
				buffer.compact();
				buffer.position(newPosition);
				indicator.reset();
				System.out.println("header bytes:");
				System.out.println(Arrays.toString(header));
				System.out.println("header string:");
				System.out.println(new String(header));
			}
		}

	}

	private static final byte[] DEMO_DATA = ("1GET /js4/main.jsp?sid=sCSUqFOkXUXnqfhAnOkkfdXUHAkXmqGf HTTP/1.1\r\n"
			+ "Host: webmail.mail.163.com\r\n"
			+ "User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.6) Gecko/20100626 SUSE/3.6.6-1.2 Firefox/3.6.6\r\n"
			+ "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
			+ "Accept-Language: zh-cn,zh;q=0.5\r\n"
			+ "Accept-Encoding: gzip,deflate\r\n"
			+ "Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7\r\n"
			+ "Keep-Alive: 115\r\n"
			+ "Connection: keep-alive\r\n"
			+ "Content-Length: 3\r\n"
			+ "\r\n"
			+ "123"
			+ "2GET /js4/main.jsp?sid=sCSUqFOkXUXnqfhAnOkkfdXUHAkXmqGf HTTP/1.1\r\n"
			+ "Host: webmail.mail.163.com\r\n"
			+ "User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.6) Gecko/20100626 SUSE/3.6.6-1.2 Firefox/3.6.6\r\n"
			+ "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
			+ "Accept-Language: zh-cn,zh;q=0.5\r\n"
			+ "Accept-Encoding: gzip,deflate\r\n"
			+ "Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7\r\n"
			+ "Keep-Alive: 115\r\n"
			+ "Connection: keep-alive\r\n"
			+ "Content-Length: 3\r\n"
			+ "\r\n"
			+ "123"
			+ "3GET /js4/main.jsp?sid=sCSUqFOkXUXnqfhAnOkkfdXUHAkXmqGf HTTP/1.1\r\n"
			+ "Host: webmail.mail.163.com\r\n"
			+ "User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.6) Gecko/20100626 SUSE/3.6.6-1.2 Firefox/3.6.6\r\n"
			+ "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
			+ "Accept-Language: zh-cn,zh;q=0.5\r\n"
			+ "Accept-Encoding: gzip,deflate\r\n"
			+ "Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7\r\n"
			+ "Keep-Alive: 115\r\n"
			+ "Connection: keep-alive\r\n"
			+ "Content-Length: 3\r\n"
			+ "\r\n"
			+ "123"
			+ "4GET /js4/main.jsp?sid=sCSUqFOkXUXnqfhAnOkkfdXUHAkXmqGf HTTP/1.1\r\n"
			+ "Host: webmail.mail.163.com\r\n"
			+ "User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.6) Gecko/20100626 SUSE/3.6.6-1.2 Firefox/3.6.6\r\n"
			+ "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
			+ "Accept-Language: zh-cn,zh;q=0.5\r\n"
			+ "Accept-Encoding: gzip,deflate\r\n"
			+ "Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7\r\n"
			+ "Keep-Alive: 115\r\n"
			+ "Connection: keep-alive\r\n"
			+ "Content-Length: 3\r\n"
			+ "\r\n"
			+ "123"
			+ "5GET /js4/main.jsp?sid=sCSUqFOkXUXnqfhAnOkkfdXUHAkXmqGf HTTP/1.1\r\n"
			+ "Host: webmail.mail.163.com\r\n"
			+ "User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.6) Gecko/20100626 SUSE/3.6.6-1.2 Firefox/3.6.6\r\n"
			+ "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
			+ "Accept-Language: zh-cn,zh;q=0.5\r\n"
			+ "Accept-Encoding: gzip,deflate\r\n"
			+ "Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7\r\n"
			+ "Keep-Alive: 115\r\n"
			+ "Connection: keep-alive\r\n"
			+ "Content-Length: 3\r\n" + "\r\n" + "123").getBytes();

	public static void main(String[] args) {
		HttpPacketReader reader = new HttpPacketReader();
		reader.read();
	}
}
